﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using VersionComparer.Base;
using VersionComparer.DataModel.Assemblies.Images;

namespace VersionComparer.DataModel.Assemblies
{
    
    [Serializable]
    public class AttributeItem : AssemblyItemBase<CustomAttributeData>
    {
        RtfBuilder rtf = new RtfBuilder();

        protected override Type AssociatedType(CustomAttributeData value)
        {
            return value.Constructor.DeclaringType;
        }
        protected override void Initialize(CustomAttributeData value)
        {
            base.Initialize(value);
            StringBuilder attributeArguments = new StringBuilder();
            StringBuilder attributeArgumentsFull = new StringBuilder();
            Text = value.ToString();
            rtf.Append ( "[");
            if (Parent is AssemblyItemsInfo)
            {
                rtf.Append("assembly", keywordColor);
                rtf.Append(":");
            }
            Name = UnderlyingTypeName;
            rtf.Append (Name, nameColor);
            bool isFirst = true ;
            foreach (CustomAttributeTypedArgument argument in value.ConstructorArguments)
            {
                if (!isFirst)
                    rtf.Append(",");
                else
                    rtf.Append("(");
                BuildParameterRtf ( argument , rtf);
                
                attributeArgumentsFull.AppendFormat("{0},", ParameterValueAsString(argument, true));
                attributeArguments.AppendFormat("{0},", ParameterValueAsString(argument, false));
                isFirst = false;
            }
            foreach (CustomAttributeNamedArgument argument in value.NamedArguments)
            {
                if (!isFirst)
                    rtf.Append(",");
                else
                    rtf.Append("(");
                BuildParameterRtf ( argument , rtf);

                attributeArgumentsFull.AppendFormat("{0},", ParameterValueAsString(argument,true));
                attributeArguments.AppendFormat("{0},", ParameterValueAsString(argument,false));
                isFirst = false;
            }
            if (!isFirst)
                rtf.Append(")");
            rtf.Append ( "]");
            Text = string.Format("[{0}({1})]",Name, attributeArguments.ToString().TrimEnd(','));
            FullText = string.Format("[{0}({1})]", UnderlyingTypeRtf.Text, attributeArgumentsFull.ToString().TrimEnd(','));
            
        }
        protected override AttributeItem[] Attributes(CustomAttributeData value)
        {
            return new AttributeItem[0];
        }
       
        private static void BuildParameterRtf(CustomAttributeTypedArgument argument, RtfBuilder builder)
        {
            BuildValueRtf(argument.ArgumentType, argument.Value, builder);
        }
        private static void BuildParameterRtf(CustomAttributeNamedArgument argument, RtfBuilder builder)
        {
            BuildParameterRtf(argument.TypedValue, builder);
        }
        private static string ParameterValueAsString(CustomAttributeTypedArgument argument, bool fullNamespace)
        {
            object value = argument.Value;
            if ( value == null )
                return "null";

            if ( argument.ArgumentType == typeof ( string))
                return string.Format("\"{0}\"", value);
            if (argument.ArgumentType.IsEnum)
                return string.Format("{0}.{1}", fullNamespace ? argument.ArgumentType.FullName : argument.ArgumentType.Name, Enum.ToObject(argument.ArgumentType, value));
            return value.ToString();
        }
        private static string ParameterValueAsString(CustomAttributeNamedArgument argument, bool fullNamespace)
        {
            return ParameterValueAsString(argument.TypedValue, fullNamespace);
        }

        protected override void BuildRtf(Base.RtfBuilder builder, bool differencesOnly, bool useParentColor)
        {
            BuildRtf(builder, differencesOnly, ! (Parent is ParameterItem ));
        }

        public void BuildRtf(Base.RtfBuilder builder, bool differencesOnly, bool useParentColor, bool addEndOfLine)
        {
            builder.Append(rtf);
            if ( addEndOfLine )
                builder.AppendLine();
        }

        protected override System.Drawing.Image GetSpecificImage()
        {
            return AssemblyResources._class;
        }


        

    }
}
